﻿using UnityEngine;
using System.IO;
using System.Collections.Generic;
using System.Xml;
using Newtonsoft.Json;

namespace com.yd.sdk
{
    public class Utils
    {
        /// <summary>
        /// 删除字符串
        /// </summary>
        /// <param name="source"></param>
        /// <param name="deleteString"></param>
        public static void DeleteStringFromFile(string source,string deleteString)
        {
            if (!File.Exists(source)) return;
            var text = File.ReadAllText(source);
            if (text.Contains(deleteString))
            {
                var insert = text.Replace(deleteString, "");
                File.WriteAllText(source,insert);
            }
        }
        
        /// <summary>
        /// //拷贝AndroidManifest
        /// </summary>
        /// <param name="source">原文件路径</param>
        /// <param name="dest">目标文件路径</param>
        public static void CopyAndroidManifest(string source,string dest)
        {
            if (!File.Exists(source)) return;
            var destDir = Application.dataPath + Constants.ANDROID_PLUGINS_PATH;
            if (!Directory.Exists(destDir))
                Directory.CreateDirectory(destDir);
            if(!File.Exists(dest))
                File.Copy(source,dest);
            
            var destXml = new XmlDocument();
            destXml.Load(dest);
            CheckPackageName(destXml.SelectSingleNode("/manifest/application"),"com.unity3d.player.MyUnityPlayerActivity");
            destXml.Save(dest);
        }

        /// <summary>
        /// 重置AndroidManifest包名
        /// </summary>
        public static void ResetAndroidManifest()
        {
            var dest = Application.dataPath + Constants.ANDROID_MAIN_MANIFEST;
            if (!File.Exists(dest)) return;
            var destXml = new XmlDocument();
            destXml.Load(dest);
            CheckPackageName(destXml.SelectSingleNode("/manifest/application"),"com.unity3d.player.UnityPlayerActivity");
            destXml.Save(dest);
            
        }


        public static void AddApplicationProperty(string name,string value)
        {
            var dest = Application.dataPath + Constants.ANDROID_MAIN_MANIFEST;
            if (!File.Exists(dest)) return;
            var destXml = new XmlDocument();
            destXml.Load(dest);

            XmlElement xmlElement = (XmlElement)destXml.SelectSingleNode("/manifest/application");
            xmlElement.SetAttribute(name, "http://schemas.android.com/apk/res/android",
                value);
            
            destXml.Save(dest);

        }

        public static void AddApplicationMetaData(string key,string value)
        {
            var dest = Application.dataPath + Constants.ANDROID_MAIN_MANIFEST;
            if (!File.Exists(dest)) return;
            var destXml = new XmlDocument();
            destXml.Load(dest);

            XmlNode applicationSource = (XmlElement)destXml.SelectSingleNode("/manifest/application");
            string elementName = "meta-data";
            bool isAlreadyExist = false;
            foreach (XmlNode element in applicationSource.ChildNodes)
            {
                if (element.Name.Equals(elementName))
                {
                    var xmlNodeKey = element.Attributes.Item(0);
                    var xmlNodeValue = element.Attributes.Item(1);

                    if (xmlNodeKey.InnerText.Equals(key))
                    {
                        isAlreadyExist = true;
                    }
                }
            }

            if (!isAlreadyExist)
            {
                XmlElement permissionElement = destXml.CreateElement(elementName);
                permissionElement.SetAttribute("name", "http://schemas.android.com/apk/res/android",
                    key);
                permissionElement.SetAttribute("value", "http://schemas.android.com/apk/res/android",
                    value);
                applicationSource.AppendChild(permissionElement);
            }

            destXml.Save(dest);
            
        }


        public static void RemoveApplicationMetaData(string key)
        {
            var dest = Application.dataPath + Constants.ANDROID_MAIN_MANIFEST;
            if (!File.Exists(dest)) return;
            var destXml = new XmlDocument();
            destXml.Load(dest);

            XmlNode applicationSource = (XmlElement)destXml.SelectSingleNode("/manifest/application");
            string elementName = "meta-data";
            bool isAlreadyExist = false;
            foreach (XmlNode element in applicationSource.ChildNodes)
            {
                if (element.Name.Equals(elementName))
                {
                    var xmlNodeKey = element.Attributes.Item(0);
                    var xmlNodeValue = element.Attributes.Item(1);

                    if (xmlNodeKey.InnerText.Contains(key))
                    {
                        applicationSource.RemoveChild(element);
                    }
                }
            }
            destXml.Save(dest);
        }

        /// <summary>
        /// 拷贝Res文件  
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        public static void CopyAndroidValues(string source, string dest)
        {
            if (!File.Exists(source)) return;
            var destDir = Application.dataPath + Constants.ANDROID_PLUGINS_RES_VALUE_PATH;
            if (!Directory.Exists(destDir))
                Directory.CreateDirectory(destDir); 
            
            if(File.Exists(dest))
                File.Delete(dest);
            
            File.Copy(source,dest);
        }

        /// <summary>
        /// 拷贝Xml文件
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        public static void CopyAndroidXml(string source, string dest)
        {
            if (!File.Exists(source)) return;
            var destDir = Application.dataPath + Constants.ANDROID_PLUGINS_RES_STRING_PATH;
            if (!Directory.Exists(destDir))
                Directory.CreateDirectory(destDir); 
            
            if(File.Exists(dest))
                File.Delete(dest);
            
            File.Copy(source,dest);
        }


        /// <summary>
        /// 用于合并strings.xml
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest">相对路径</param>
        public static void MergeAndroidValuesString(string source, string dest)
        {
            if (!File.Exists(source)) return;
            var destDir = Application.dataPath + Constants.ANDROID_PLUGINS_RES_VALUE_PATH;
            if (!Directory.Exists(destDir))
                Directory.CreateDirectory(destDir); 
            if(!File.Exists(dest))
                //复制
                File.Copy(source,dest);
            
            //合并
            var sourceXml = new XmlDocument();
            sourceXml.Load(source);
            var destXml = new XmlDocument();
            destXml.Load(dest);
            CheckResValuesStrings(sourceXml.SelectSingleNode("/resources"),
                destXml.SelectSingleNode("/resources"), destXml);
            destXml.Save(dest);
        }
        
        /// <summary>
        /// 合并Gradle依赖项
        /// </summary>
        /// <param name="source"></param>
        /// <param name="implementation"></param>
        public static void MergeDependenciesInGradle(string source,string implementation)
        {
            if (!File.Exists(source)) return;
            var text = File.ReadAllText(source);
            if (text.Contains(implementation) == false)
            {
                var index = text.IndexOf("**DEPS**");
                if (index != -1)
                {
                    var insert = text.Insert(index, "\t"+implementation+"\r");
                    File.WriteAllText(source,insert);
                }
            }
        }
        
        /// <summary>
        /// 用來合并AndroidManifest.xml (不会去操做没有就复制)
        /// </summary>
        /// <param name="source">原文件路径</param>
        /// <param name="dest">目标文件路径</param>
        public static void MergeAndroidManifest(string source, string dest)
        {
            if (!File.Exists(source) || !File.Exists(dest)) return;

            var sourceXml = new XmlDocument();
            sourceXml.Load(source);
            var destXml = new XmlDocument();
            destXml.Load(dest);

            
            CheckUsesPermission(sourceXml.SelectSingleNode("/manifest"), destXml.SelectSingleNode("/manifest"),
                destXml);
            CheckMetaData(sourceXml.SelectSingleNode("/manifest/application"),
                destXml.SelectSingleNode("/manifest/application"), destXml);
            destXml.Save(dest);
        }

        /// <summary>
        /// 检查目标AndroidManifest.xml中的启动包名
        /// </summary>
        /// <param name="activityNode"></param>
        private static void CheckPackageName(XmlNode application,string packageName)
        {
            var elementName = "activity";
            var action = "android.intent.action.MAIN";
            var packageKey = "android:name";
            foreach (XmlNode element in application.ChildNodes)
            {
                if (element.Name.Equals(elementName))
                {
                    var actionNode = element.SelectSingleNode("intent-filter/action");
                    if (actionNode != null && actionNode.Attributes.Item(0).InnerText.Contains(action))
                    {
                        foreach (XmlAttribute attribute in element.Attributes)
                        {
                            if (packageKey.Equals(attribute.Name))
                            {
                                attribute.InnerText = packageName;
                                // Debug.Log(attribute.Name);
                                // Debug.Log(attribute.InnerText);
                            }
                        }
                    }
                    
                    // if (actionNode != null &&action.Equals())
                    // {
                    //     Debug.Log(actionNode.Attributes.Item(0).InnerText);
                    //     //&& action.Equals(actionNode.Attributes.Item(0).InnerText)
                    // }

                    // var xmlNodeKey = element.Attributes.Item(0);
                    // var xmlNodeValue = element.Attributes.Item(1);
                    //
                    // if (!needWriteMetaData.ContainsKey(xmlNodeKey.InnerText))
                    //     needWriteMetaData.Add(xmlNodeKey.InnerText, xmlNodeValue.InnerText);
                }
            }
        }

        /// <summary>
        /// 检查资源strings.xml中的string标签
        /// </summary>
        /// <param name="stringsSource"></param>
        /// <param name="stringsDest"></param>
        private static void CheckResValuesStrings(XmlNode stringsSource,XmlNode stringsDest,XmlDocument destXml)
        {
            if (stringsSource == null || stringsDest == null) return;
            
            var needWriteStrings = new Dictionary<string, string>();
            foreach (XmlElement element in stringsSource.ChildNodes)
            {
                if (element.Name.Equals("string"))
                {
                    var xmlNode = element.Attributes.Item(0);
                    if (!needWriteStrings.ContainsKey(xmlNode.InnerXml))
                        needWriteStrings.Add(xmlNode.InnerXml, element.InnerText);
                }
            }
            
            var hasStrings = new Dictionary<string, string>();
            foreach (XmlElement element in stringsDest.ChildNodes)
            {
                if (element.Name.Equals("string"))
                {
                    var xmlNode = element.Attributes.Item(0);
                    if (!hasStrings.ContainsKey(xmlNode.InnerXml))
                        hasStrings.Add(xmlNode.InnerXml, element.InnerText);
                }
            }
            
            foreach (var permission in needWriteStrings)
            {
                if (!hasStrings.ContainsKey(permission.Key))
                {
                    XmlElement permissionElement = destXml.CreateElement("string");
                    permissionElement.SetAttribute("name", permission.Key);
                    string result = "";
                    if ("facebook_app_id".Equals(permission.Key))
                    {
                        result = SDKEditorWindow.sdkSettings.Facebook_app_id;
                        if(string.IsNullOrEmpty(result))
                            Debug.LogError("请前往Resources/SDK_CONFIG配置facebook_app_id");
                    }else if ("fb_login_protocol_scheme".Equals(permission.Key))
                    {
                        result = SDKEditorWindow.sdkSettings.Fb_login_protocol_scheme;
                        if(string.IsNullOrEmpty(result))
                            Debug.LogError("请前往Resources/SDK_CONFIG配置fb_login_protocol_scheme");
                    }else
                        result = permission.Value;
                    if (!string.IsNullOrEmpty(result))
                    {
                        permissionElement.InnerText = permission.Value;
                        stringsDest.AppendChild(permissionElement);
                        Debug.Log("<color=#00FF00>成功合并strings.xml</color>");
                    }
                }
                else
                    Debug.LogError("strings.xml中产生相同的key:" + permission.Key);
            }
        }
        
        /// <summary>
        /// 检测用户权限
        /// </summary>
        /// <param name="manifestNodeSource"></param>
        /// <param name="manifestNodeDest"></param>
        /// <param name="destXml"></param>
        private static void CheckUsesPermission(XmlNode manifestNodeSource, XmlNode manifestNodeDest,
            XmlDocument destXml)
        {
            if (manifestNodeSource == null || manifestNodeDest == null) return;

            var needWritePermission = new Dictionary<string, bool>();
            foreach (XmlElement element in manifestNodeSource.ChildNodes)
            {
                if (element.Name.Equals("uses-permission"))
                {
                    var xmlNode = element.Attributes.Item(0);
                    if (!needWritePermission.ContainsKey(xmlNode.InnerText))
                        needWritePermission.Add(xmlNode.InnerText, true);
                }
            }

            var hasPermission = new Dictionary<string, bool>();
            foreach (XmlElement element in manifestNodeDest.ChildNodes)
            {
                if (element.Name.Equals("uses-permission"))
                {
                    var xmlNode = element.Attributes.Item(0);
                    if (!hasPermission.ContainsKey(xmlNode.InnerText))
                        hasPermission.Add(xmlNode.InnerText, true);
                }
            }

            foreach (var permission in needWritePermission)
            {
                if (!hasPermission.ContainsKey(permission.Key))
                {
                    XmlElement permissionElement = destXml.CreateElement("uses-permission");
                    permissionElement.SetAttribute("name", "http://schemas.android.com/apk/res/android",
                        permission.Key);
                    manifestNodeDest.AppendChild(permissionElement);
                }
            }

        }

        /// <summary>
        /// 检测Meta-data
        /// </summary>
        /// <param name="applicationSource"></param>
        /// <param name="applicationDest"></param>
        /// <param name="destXml"></param>
        private static void CheckMetaData(XmlNode applicationSource, XmlNode applicationDest, XmlDocument destXml)
        {
            var elementName = "meta-data";
            if (applicationSource == null || applicationDest == null) return;

            var needWriteMetaData = new Dictionary<string, string>();
            foreach (XmlNode element in applicationSource.ChildNodes)
            {
                if (element.Name.Equals(elementName))
                {
                    var xmlNodeKey = element.Attributes.Item(0);
                    var xmlNodeValue = element.Attributes.Item(1);

                    if (!needWriteMetaData.ContainsKey(xmlNodeKey.InnerText))
                        needWriteMetaData.Add(xmlNodeKey.InnerText, xmlNodeValue.InnerText);
                }
            }

            var hasMetaData = new Dictionary<string, bool>();
            foreach (XmlNode element in applicationDest.ChildNodes)
            {
                if (element.Name.Equals(elementName))
                {
                    var xmlNodeKey = element.Attributes.Item(0);
                    if (needWriteMetaData.ContainsKey(xmlNodeKey.InnerText))
                    {
                        if ("com.google.android.gms.ads.APPLICATION_ID".Equals(xmlNodeKey.InnerText))
                        {
                            if (string.IsNullOrEmpty(SDKEditorWindow.sdkSettings.ADS_APPLICATION_ID))
                            {
                                Debug.LogError("请前往SDK_CONFIG配置APPLICATION_ID");
                            }
                            else
                            {
                                element.Attributes.Item(1).InnerText = SDKEditorWindow.sdkSettings.ADS_APPLICATION_ID;
                            }
                        }else if ("adjust_id".Equals(xmlNodeKey.InnerText))
                        {
                            if (string.IsNullOrEmpty(SDKEditorWindow.sdkSettings.Adjust_Token))
                            {
                                Debug.LogError("请前往SDK_CONFIG配置Adjust_Token");
                            }
                            else
                            {
                                element.Attributes.Item(1).InnerText = SDKEditorWindow.sdkSettings.Adjust_Token;
                            }
                        }
                        else
                        {
                            //如果写入的值中已经存在原文件中
                            element.Attributes.Item(1).InnerText = needWriteMetaData[xmlNodeKey.InnerText];
                        }

                        needWriteMetaData.Remove(xmlNodeKey.InnerText);
                    }else if (!hasMetaData.ContainsKey(xmlNodeKey.InnerText))
                        hasMetaData.Add(xmlNodeKey.InnerText, true);
                }
            }

            foreach (var permission in needWriteMetaData)
            {
                if (!hasMetaData.ContainsKey(permission.Key))
                {
                    XmlElement permissionElement = destXml.CreateElement(elementName);
                    permissionElement.SetAttribute("name", "http://schemas.android.com/apk/res/android",
                        permission.Key);

                    if ("com.google.android.gms.ads.APPLICATION_ID".Equals(permission.Key))
                    {
                        if (string.IsNullOrEmpty(SDKEditorWindow.sdkSettings.ADS_APPLICATION_ID))
                        {
                            Debug.LogError("请前往SDK_CONFIG配置APPLICATION_ID");
                        }
                        else
                        {
                            permissionElement.SetAttribute("value", "http://schemas.android.com/apk/res/android",
                                SDKEditorWindow.sdkSettings.ADS_APPLICATION_ID);
                        }
                    }else if ("adjust_id".Equals(permission.Key))
                    {
                        if (string.IsNullOrEmpty(SDKEditorWindow.sdkSettings.Adjust_Token))
                        {
                            Debug.LogError("请前往SDK_CONFIG配置Adjust_Token");
                        }
                        else
                        {
                            permissionElement.SetAttribute("value", "http://schemas.android.com/apk/res/android",
                                SDKEditorWindow.sdkSettings.Adjust_Token);
                        }
                    }
                    else
                    {
                        permissionElement.SetAttribute("value", "http://schemas.android.com/apk/res/android",
                            permission.Value);
                    }
                    
                    applicationDest.AppendChild(permissionElement);
                }
            }


        }


        /// <summary>
        /// 替换GoogleService.json
        /// </summary>
        /// <param name="dest"></param>
        public static void ReplaceGoogleService(string dest)
        {
            if (!File.Exists(dest)) return;

            if (SDKEditorWindow.sdkSettings.Google_Services_Json == null)
            {
                Debug.LogError("请前往Resources/SDK_CONFIG配置Google_Services_Json");
            }
            else
            {
                string file = File.ReadAllText(dest);
                var googleServiceVo = JsonConvert.DeserializeObject<GoogleServicesVo>(SDKEditorWindow.sdkSettings.Google_Services_Json.text);
                file = file.Replace("@firebase_database_url", googleServiceVo.project_info.firebase_url);
                file = file.Replace("@gcm_defaultSenderId", googleServiceVo.project_info.project_number);
                file = file.Replace("@google_storage_bucket", googleServiceVo.project_info.storage_bucket);
                file = file.Replace("@project_id", googleServiceVo.project_info.project_id);
                file = file.Replace("@google_api_key", googleServiceVo.client[0].api_key[0].current_key);
                file = file.Replace("@google_crash_reporting_api_key", googleServiceVo.client[0].api_key[0].current_key);
                file = file.Replace("@google_app_id", googleServiceVo.client[0].client_info.mobilesdk_app_id);
                file = file.Replace("@default_web_client_id", googleServiceVo.client[0].oauth_client[0].client_id);
                File.WriteAllText(dest,file);
                Debug.Log("<color=#00FF00>成功合并Google-Services.xml</color>");
            }
            
            
            // if (text.Contains(implementation) == false)
            // {
            //     var index = text.IndexOf("**DEPS**");
            //     if (index != -1)
            //     {
            //         var insert = text.Insert(index, "\t"+implementation+"\r");
            //         File.WriteAllText(source,insert);
            //     }
            // }

            
            
        }

    }

    //
    //     /// <summary>
    //     /// 用于解析xml的方法
    //     /// </typeparam>
    //     /// <param name="path">xml文件的路径</param>
    //     /// <param name="ms">用于接受xml文件解析的结果</param>
    //     public static void LoadXml<T>(string path,ref T ms) where T :class
    //     {
    //         try
    //         {
    //             //通过流根据路径去读取文件
    //             using(TextReader reader = new StreamReader(path))
    //             {
    //                 var serializer = new XmlSerializer(typeof(T));
    //                 var item = (T)serializer.Deserialize(reader);
    //                 if (item!= null)
    //                 {
    //                     ms = item;
    //                 }
    //             }
    //         }
    //         catch(Exception ex)
    //         {
    //             //用于捕捉异常避免解析过程中出现错误导致程序死掉
    //             //将错误打印出来
    //             Debug.LogError(ex.Message);
    //         }
    //     }
    // }
    //
    // [XmlRoot("manifest")]
    // public class Manifest
    // {
    //     [XmlAttribute(AttributeName = "xmln:android")]
    //     public string xmlns_android { set; get; }
    //     
    //     [XmlAttribute(AttributeName = "package")]
    //     public string package { set; get; }
    //
    //     [XmlAttribute(AttributeName = "xmlns:tools")]
    //     public string xmlns_tools { set; get; }
    //
    //     [XmlElement("application")]
    //     public ManifestApplication application { set; get; }
    //     
    //     [XmlElement("meta-data")]
    //     public MetaData[] metaData{set;get;}
    // }
    //
    // public class ManifestApplication
    // {
    //     [XmlElement("activity")]
    //     public ManifestActivity manifestActivity;
    // }
    //
    // public class ManifestActivity
    // {
    //     [XmlAttribute(AttributeName = "android:name")]
    //     public string name { set; get; }
    //     [XmlAttribute(AttributeName = "android:theme")]
    //     public string theme { set; get; }
    //
    //     [XmlElement("intent-filter")]
    //     public IntentFilter intentFilter { set; get; }
    //
    //     [XmlElement("meta-data")]
    //     public MetaData[] metaData{set;get;}
    //     
    // }
    //
    // public class IntentFilter
    // {
    //     [XmlElement("action")]
    //     public Action action;
    //
    //     [XmlElement("category")]
    //     public Category category;
    // }
    //
    // public class Action
    // {
    //     [XmlAttribute(AttributeName = "android:name")]
    //     public string name { set; get; }
    // }
    //
    // public class Category
    // {
    //     [XmlAttribute(AttributeName = "android:name")] 
    //     public string name { set; get;}
    // }
    //
    // public class MetaData
    // {
    //     [XmlAttribute(AttributeName = "android:name")]
    //     public string name { set; get; }
    //     [XmlAttribute(AttributeName = "android:value")]
    //     public string value { set; get; }
    // }


    

}
